// pages/kitchen-scale/kitchen-scale.js
const { QNMPPlugin, QNConsts, QNBleProtocols } = requirePlugin('QNBleApi');

const { KitchenBleScaleProtocol } = QNBleProtocols;

const BleOpStatusEnum = {
  // 初始状态，未init前
  NOOP: 'NOOP',
  // 蓝牙不可用
  BLE_DISABLED: 'BLE_DISABLED',
  // 蓝牙可用
  BLE_READY: 'BLE_READY',
  // 正在扫描
  SCANNING: 'SCANNING',
  // 停止扫描
  STOP_SCANNING: 'STOP_SCANNING',
  // 已发现设备
  DEVICE_FOUNDED: 'DEVICE_FOUNDED',
  // 正在连接
  CONNECTING: 'CONNECTING',
  // 已连接
  CONNECTED: 'CONNECTED',
  // 连接失败
  CONNECT_FAILED: 'CONNECT_FAILED',
  // 断开连接
  DISCONNECTED: 'DISCONNECTED',
  // 连接超时
  CONNECT_OVERTIME: 'CONNECT_OVERTIME',
  // 例如：正在测量
  OPERATING: 'OPERATING',
  // 例如：测量完成
  OPERATE_FINISHED: 'OPERATE_FINISHED',
  // 发生了错误
  ERROR_OCCURED: 'ERROR_OCCURED',
};

/**
 * 微信的本地日志功能，需要用户手动反馈才能拿到日志文件
 */
const logger = () => {
  const wxlogger =
    wx.getLogManager &&
    wx.getLogManager({
      level: 0,
    });
  const log = (...params) => {
    console.log(...params);
    wxlogger && wxlogger.log(...params);
  };
  return {
    log,
  };
};

function defaultScaleData() {
  return {
    // 重量。单位为g
    weight: 0,
    // 小数点保留位数
    weightPrecision: 0,
    /**
     * QNConsts.QNBleUnit
     * g: 克
     * ml: 毫升
     * milkml: ml(牛奶)
     * fl.oz: fl.oz单位
     * lb:oz: lb:oz单位
     */
    weightUnit: 'g',
    // 是否是去皮模式
    isPeeled: false,
    // 是否超重
    isOverWeight: false,
    // 重量是否已稳定
    isSteady: false,
    // 设备蓝牙版本
    bleVersion: 0,
    // 设备固件版本
    scaleVersion: 0,
  };
}

function unitTransform(value, unit, weightPrecision = 1) {
  let calc = value;
  const isNegative = value < 0;
  switch (unit) {
    case QNConsts.QNBleUnit.FLOZ:
      calc = (0.035274 * value).toFixed(weightPrecision + 1);
      break
    case QNConsts.QNBleUnit.LBOZ:
      calc = Math.abs(0.035274 * value);
      calc = `${isNegative ? '-' : ''}${Math.floor(calc / 16)}:${(calc % 16).toFixed(weightPrecision + 1)}`;
      break
    case QNConsts.QNBleUnit.MILKML:
      calc = (value / 1.03).toFixed(weightPrecision);
      break
    case QNConsts.QNBleUnit.G:
    case QNConsts.QNBleUnit.ML:
    default:
      calc = value.toFixed(weightPrecision);
      break
  }
  return calc;
}

Page({

  /**
   * 页面的初始数据
   */
  data: {
    deviceId: '',
    connected: false,
    connecting: false,
    bleOpStatus: BleOpStatusEnum.NOOP,
    bleOpStatusText: '初始化中...',
    // 蓝牙可用状态
    bleEnableState: false,
    controlGroup: [
      {
        value: 1,
        name: 'g',
      },
      {
        value: 2,
        name: 'ml',
      },
      {
        value: 4,
        name: 'ml(牛奶)',
      },
      {
        value: 8,
        name: 'fl.oz',
      },
      {
        value: 0x10,
        name: 'lb:oz',
      },
      {
        value: 0x20,
        name: '去皮',
      },
    ],
    controlRadioValue: -1,
    standbyTimeGroup: [
      {
        value: 1,
        name: '2分钟',
      },
      {
        value: 2,
        name: '3.5分钟',
      },
      {
        value: 3,
        name: '5分钟',
      },
    ],
    standbyTimeRadioValue: -1,
    hasReceivedScaleData: false,
    scaleData: defaultScaleData(),
    weightText: '',
  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
    /**
     * 判断相关权限是否开启, 根据需求放在合适的位置
     * locationEnabled 是否开启定位
     * locationAuthorized 是否授权定位(仅安卓需要,需要选择始终允许,不能选择询问,因为微信不会询问用户是否开启定位)
     * bluetoothEnabled 蓝牙是否开启
     */
    // const { locationAuthorized, locationEnabled, bluetoothEnabled } = wx.getSystemInfoSync();
    // if (!locationAuthorized || !locationEnabled || !bluetoothEnabled) {
    //   this.tip('请确认相关权限是否开启');
    //   setTimeout(() => {
    //     wx.navigateBack();
    //   }, 2000);
    // }

    // 初始化蓝牙
    this.bleApi = new QNMPPlugin({
      useSdk: false,
      logger: logger(), // 非必须，日志功能，最好有，方便排查问题，可以替换为客户自己的
      protocols: [KitchenBleScaleProtocol],
    });

    // 错误监听
    this.bleApi.onError = (err) => {
      this.updateBleOpStatus(BleOpStatusEnum.ERROR_OCCURED);
      console.error('捕捉到错误', err.detail);
      wx.showToast({
        title: `发生了错误.[error]: ${err.message}`,
        icon: 'error',
      })
    };

    // 初始化回调
    this.bleApi.onReady = ({
      bleEnableState, // 表示当前蓝牙是否为开启状态
    }) => {
      if (bleEnableState) {
        this.updateBleOpStatus(BleOpStatusEnum.BLE_READY);
        this.setData({ bleEnableState: true });
        // this.bleApi.startBleDeviceDiscovery();
      } else {
        console.log('蓝牙状态为关闭');
        this.updateBleOpStatus(BleOpStatusEnum.BLE_DISABLED);
      }
    };

    // 设置蓝牙监听事件
    this.bleApi.setBleEventListener(this.bleEventListener());

    // 初始化
    this.bleApi.init();
  },

  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady: function () {

  },

  /**
   * 生命周期函数--监听页面显示
   */
  onShow: function () {

  },

  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide: function () {

  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload: function () {
    if (this.bleApi) {
      this.bleApi.stop();
    }
  },

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh: function () {

  },

  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom: function () {

  },

  /**
   * 用户点击右上角分享
   */
  onShareAppMessage: function () {

  },

  updateBleOpStatus(status) {
    let text = '';
    switch (status) {
      case BleOpStatusEnum.NOOP:
        text = '初始化中...';
        break;
      case BleOpStatusEnum.BLE_DISABLED:
        text = '蓝牙不可用';
        break;
      case BleOpStatusEnum.BLE_READY:
        text = '请将手机靠近设备进行连接';
        break;
      case BleOpStatusEnum.SCANNING:
        text = '正在扫描设备';
        break;
      case BleOpStatusEnum.DEVICE_FOUNDED:
        text = '已发现设备';
        break;
      case BleOpStatusEnum.CONNECTING:
        text = '正在连接...';
        break;
      case BleOpStatusEnum.STOP_SCANNING:
        text = '停止扫描';
        break;
      case BleOpStatusEnum.CONNECTED:
        text = '已连接';
        break;
      case BleOpStatusEnum.CONNECT_FAILED:
        text = '连接设备失败';
        break;
      case BleOpStatusEnum.DISCONNECTED:
        text = '断开连接';
        break;
      case BleOpStatusEnum.CONNECT_OVERTIME:
        text = '连接超时';
        break;
      case BleOpStatusEnum.OPERATING:
        text = '正在测量';
        break;
      case BleOpStatusEnum.OPERATE_FINISHED:
        text = '重量已稳定';
        break;
      case BleOpStatusEnum.ERROR_OCCURED:
        text = '发生了错误';
        break;
      default:
        break;
    }

    this.setData({
      bleOpStatus: status,
      bleOpStatusText: text,
    });
  },
 
  // 蓝牙相关事件回调
  bleEventListener() {
    /**
     * 监听扫描到设备的回调
     */
    const onBleDeviceFound = (device) => {
      // 测试时这里可过滤mac来方便连接
      // if (device.mac === 'FF:F2:00:06:1D:AB') {
      //   this.updateBleOpStatus(BleOpStatusEnum.DEVICE_FOUNDED);
      //   this.handleConnect(device);
      // }

      this.updateBleOpStatus(BleOpStatusEnum.DEVICE_FOUNDED);
      this.handleConnect(device);
    };

    /**
     * 监听蓝牙断开连接的回调
     */
    const onDisconnected = (device) => {
      this.updateBleOpStatus(BleOpStatusEnum.DISCONNECTED);
      this.setData({
        connected: false,
      });
      console.log('设备连接已断开', device);
    };

    /**
     * 监听蓝牙状态发生变化回调，连接成功或断开连接都会出触发
     */
    const onBluetoothEnableChange = ({ available }) => {
      console.log('onBluetoothEnableChange', available);
      this.setData({ bleEnableState: available });
      if (available) {
        this.updateBleOpStatus(BleOpStatusEnum.BLE_READY);
        // this.bleApi.startBleDeviceDiscovery();
      } else {
        this.updateBleOpStatus(BleOpStatusEnum.BLE_DISABLED);
      }
    };

    /**
     * 	监听设备连接成功回调
     */
    const onConnected = (device) => {
      this.updateBleOpStatus(BleOpStatusEnum.CONNECTED);
      console.log('设备已连接', device);
      this.setData({
        connected: true,
        connecting: false,
        deviceId: device.deviceId,
      });
    };

    /**
     * 监听停止扫描的回调
     */
    const onStopDiscoveryDevice = () => {
      if (this.data.bleOpStatus !== BleOpStatusEnum.CONNECTING) {
        this.updateBleOpStatus(BleOpStatusEnum.STOP_SCANNING);
      }
    };

    /**
     * 监听开始扫描设备的回调
     */
    const onStartDiscoveryDevice = () => {
      this.updateBleOpStatus(BleOpStatusEnum.SCANNING);
    };

    /**
     * 连接超时
     */
    const onConnectOverTime = () => {
      this.updateBleOpStatus(BleOpStatusEnum.CONNECT_OVERTIME);
      this.setData({
        connecting: false,
      });
    }

    return {
      onBleDeviceFound,
      onDisconnected,
      onBluetoothEnableChange,
      onConnected,
      onStopDiscoveryDevice,
      onStartDiscoveryDevice,
      onConnectOverTime,
    };
  },

  async handleConnect(device) {
    const { connecting } = this.data;
    if (connecting) {
      console.log('当前正在连接，不再处理');
      return;
    }
    this.setData({ connecting: true });
    this.updateBleOpStatus(BleOpStatusEnum.CONNECTING);

    await this.bleApi.createBleConnection(device, this.deviceEventListener());
  },

  // 秤端相关事件回调
  deviceEventListener() {
    /**
     * 获取秤端数据
     * 注意这个方法会大概间隔200ms一直回调
     */
    const onGetKitchenBleScalePublicData = (scaleData) => {
      this.setData({ scaleData, weightText: this.resolveWeightText(scaleData), hasReceivedScaleData: true });
    };

    /**
     * 设置功能结果状态
     */
    const onSetControlResult = () => {
      wx.showToast({
        title: '设置成功',
        icon: 'success',
      });
    };

    /**
     * 处于去皮模式
     */
    const onInPeelMode = () => {
      wx.showToast({
        title: '去皮模式',
        icon: 'none',
      })
    };

    /**
     * 设置待机时间成功状态
     * 需要设备支持才行
     */
    // const onSetStandbyTimeResult = () => {
    //   wx.showToast({
    //     title: '设置成功',
    //     icon: 'success',
    //   });
    // };

    return {
      onGetKitchenBleScalePublicData,
      onSetControlResult,
      onInPeelMode,
      // onSetStandbyTimeResult,
    };
  },

  onControlRadioGroupChange(e) {
   this.setData({
    controlRadioValue: Number(e.detail.value),
   });
  },

  onStandbyTimeRadioGroupChange(e) {
    this.setData({
      standbyTimeRadioValue: Number(e.detail.value),
    });
  },

  /**
   * 设置单位，去皮，关机等操作
   */
  doSetControl() {
    if (this.data.controlRadioValue >= 0) {
      if (this.bleApi) {
        this.bleApi.callProtocolMethodAsync(this.data.deviceId, 'doSetControl', [{ control: this.data.controlRadioValue }]);
      }
    } else {
      wx.showToast({
        title: '请先选择一项进行设置',
        icon: 'none',
      })
    }
  },

  /**
   * 设置待机时间
   */
  doSetStandbyTime() {
    if (this.data.standbyTimeRadioValue >= 0) {
      if (this.bleApi) {
        this.bleApi.callProtocolMethodAsync(this.data.deviceId, 'doSetStandbyTime', [{ control: this.data.standbyTimeRadioValue }]);
       }
    } else {
      wx.showToast({
        title: '请先选择一项进行设置',
        icon: 'none',
      })
    }
  },

  startClick() {
    if (this.bleApi) {
      this.bleApi.startBleDeviceDiscovery();
    }
  },

  stopClick() {
    if (this.bleApi) {
      this.bleApi.stop().then(() => {
        this.setData({ scaleData: defaultScaleData(), weightText: '', hasReceivedScaleData: false });
      });
    }
  },

  /**
   * 对重量进行单位转换
   */
  resolveWeightText(scaleData) {
    return unitTransform(scaleData.weight, scaleData.weightUnit, scaleData.weightPrecision);
  },
})